# -*- coding: utf8 -*-
from apscheduler.schedulers.background import BackgroundScheduler
from queue import Queue
from .quality_task_sql import *
from ..memcachedconnection import memcachcon
from .audio_ASR import *
import time
import re
from threading import Thread
import ast
import math
from ..projectsql.robotsql import Voicerecognition, mongorobot, p, conn, aliyundata
from dateutil.parser import parse
from ...zyrobot.decorators import time_statistic

import logging
qa_logger = logging.getLogger('qa_logger')

# s = sched.scheduler(time.time, time.sleep)
# from ..projectsql.robotsql import aliyundata
accessKeyId = "LTAI5Vz3cU71J93J"
accessKeySecret = "Koqk8ExIUJREclyzGC7J8Dz1Ljylkg"
appKey = "jSf4MZpFzzKSW1ww"


aliyunqulityqueue = Queue(maxsize=0)
aliyunqulityallnum = len(aliyundata)
for i in range(aliyunqulityallnum):
    # 写入队列数据
    aliyunqulityqueue.put(i)

overstressing = []


def timing_job():
    # global aliyunqulityqueue
    qa_logger.info('START CRON TASK')
    aliyunqulityqueue.queue.clear()
    aliyunqulityallnum = len(aliyundata)
    for i in range(aliyunqulityallnum):
        # 写入队列数据
        aliyunqulityqueue.put(i)
    overstressing = []


scheduler33 = BackgroundScheduler()
scheduler33.add_job(timing_job, 'cron', hour=1, minute=1)
scheduler33.start()


# 存储开始质检标志
# @time_statistic(0, 'task_id')
def begin_quality_task_memcached(task_id, cmpid, data):
    memcachcon.set_cach_not_time(
        '{}begin_quality_test_task{}'.format(conn.basedbname, task_id), data)


# 获取阿里云录音翻译结果
# @time_statistic(2, 'taskid')
def get_reault_voice_translate(voice_taskid, sampleid, taskid, cmpid):
    # code 1:成功 2:等待 3:录音为空 4:返回错误 5：过期 -1:调用错误
    key = memcachcon.if_exist(
        str(conn.basedbname) + 'taskid' + str(voice_taskid))
    vocie_back_code_data = {'code': '-1', 'result': ''}
    data_num = 0
    if key:
        data_num = key["data"]
        vocie_back_code_data = get_audio_asr_result(voice_taskid, key["accessKeyId"], key["accessKeySecret"])
    else:
        vocie_back_code_data = get_audio_asr_result(voice_taskid, accessKeyId, accessKeySecret)
    qa_logger.info('task_id:%s sampleid:%s vocie_back_code_data:%s', taskid, sampleid, vocie_back_code_data)
    if vocie_back_code_data['code'] == '1':

        # 更新阿里云录音翻译的结果并匹配质检规则
        updata_quality_voice_taskid('', taskid, sampleid, str(
            vocie_back_code_data['result']), 1)
        memcachcon.del_cach(str(conn.basedbname) +
                            'taskid' + str(voice_taskid))
        insert_wordlist(vocie_back_code_data['word'], taskid, sampleid, 2, '')
        return {'code': '1', 'result': vocie_back_code_data['result']}
    elif vocie_back_code_data['code'] == '2':
        # 继续等待
        # updata_quality_voice_taskid('', taskid, sampleid, '', 2)
        return {'code': '2', 'result': ''}
    elif vocie_back_code_data['code'] == '3':
        # 直接更新结果 文件不存在或内容为空
        # unusual_voice_soce(cmpid, taskid, voice_result, sampleid)
        updata_quality_voice_taskid('', taskid, sampleid, '', 4)
        memcachcon.del_cach(str(conn.basedbname) +
                            'taskid' + str(voice_taskid))
        del_quality_data(sampleid, taskid)  # 删除之前的记录
        unusual_voice_soce(cmpid, taskid, sampleid, 5, 1)

        return {'code': '3', 'result': ''}
    elif vocie_back_code_data['code'] == '4':
        # 更新结果录音文件有问题
        updata_quality_voice_taskid('', taskid, sampleid, '', 5)
        memcachcon.del_cach(str(conn.basedbname) +
                            'taskid' + str(voice_taskid))
        del_quality_data(sampleid, taskid)  # 删除之前的记录
        unusual_voice_soce(cmpid, taskid, sampleid, 5, 1)

        return {'code': '4', 'result': ''}
    elif vocie_back_code_data['code'] == '5':
        # 录音文件识别过期
        restart_translate(taskid, sampleid)
        memcachcon.del_cach(str(conn.basedbname) +
                            'taskid' + str(voice_taskid))
        return {'code': '5', 'result': ''}
    elif vocie_back_code_data['code'] == '6':  # 单日时间超限
        # 记录已经用超的次数
        overstressing.append(data_num)
        memcachcon.del_cach(str(conn.basedbname) +
                            'taskid' + str(voice_taskid))
        restart_translate(taskid, sampleid)  # 重新调用翻译
        return {'code': '6', 'result': ''}
    else:
        updata_quality_voice_taskid('', taskid, sampleid, '', 5)
        memcachcon.del_cach(str(conn.basedbname) +
                            'taskid' + str(voice_taskid))
        del_quality_data(sampleid, taskid)  # 删除之前的记录
        unusual_voice_soce(cmpid, taskid, sampleid, 5, 1)
        return {'code': '-1', 'result': ''}


# 循环插入
stop_word = ['啊', '阿', '哎', '哎呀', '哎喲', '呢', '吗', '阿', '嗯', '恩', '吖']

# @time_statistic(1, 'taskid')
def insert_wordlist(wordlist, taskid, custid, qtype, Channel_type):
    try:  # qtype 2json格式 1.list格式
        qa_logger.info('task_id:%s wordlist:%s custid:%s', taskid, wordlist, custid)
        for word in wordlist:
            if qtype == 2:
                if word['Word'] not in stop_word:
                    insert_word(word['Word'], taskid,
                                custid, word['ChannelId'])
            else:
                if word not in stop_word:
                    insert_word(word, taskid, custid, Channel_type)
    except Exception as e:
        qa_logger.error('taskid:%s error:%s %s', taskid, type(e), str(e))
        weixin_push(str(taskid), str(e), '质检错误insert_wordlist')


# 质检计费
# @time_statistic(0, 'taskid')
def billing(taskid, cmpid, quality_time, sampleid):
    try:
        # 查询余额和质检计费c.checkfee,c.balance
        qa_logger.info('task_id:%s sampleid:%s cmpid:%s quality_time:%s', taskid, sampleid, cmpid, quality_time)
        free = billing_balance(taskid, cmpid)
        checkfree = free[0]['checkfee']
        balance = free[0]['balance']
        all_money = 0
        the_end_money = 0
        alltime = math.ceil(float(quality_time) / 60)
        qa_logger.info('task_id:%s sampleid:%s  alltime:%s', taskid, sampleid, alltime)

        if checkfree != None:
            all_money = float(alltime * checkfree)
            qa_logger.info('task_id:%s sampleid:%s  all_money:%s', taskid, sampleid, all_money)
            # 插入计费列表
            insert_bulling(cmpid, quality_time, all_money, sampleid, taskid)
            # 更新余额
            if balance != None:
                the_end_money = float(balance) - float(all_money)
            else:
                the_end_money = - float(all_money)
            updata_balance(cmpid, taskid, the_end_money)
    except Exception as e:
        weixin_push(str(taskid), str(e), '质检错误billing')
        qa_logger.error('taskid:%s error:%s %s', taskid, type(e), str(e))


# 存储异常文件的分数
# @time_statistic(1, 'taskid')
def unusual_voice_soce(cmpid, taskid, sampleid, state, q_type):
    try:
        rules_list = sel_taskid_rules(taskid)
        for rules in rules_list:
            insert_rule_score(rules['ruleid'], 0, sampleid, 2, taskid)
        if q_type == 1:
            statistics_score(cmpid, taskid, {'BizDuration': 0, 'Result': {'Words': [], 'Sentences': []}}, 0, sampleid,
                             state, 0, None, '')
    except Exception as e:
        weixin_push(str(taskid), str(e), '质检错误unusual_voice_soce')
        qa_logger.error('taskid:%s error:%s %s', taskid, type(e), str(e))


# 移除已经用完的appkey
# @time_statistic(0,'file_link')
def voice_translate_use_aliyun(file_link):
    data = int(aliyunqulityqueue.get(timeout=5))
    try:
        accessKeyId = aliyundata[data]["keyid"]
        accessKeySecret = aliyundata[data]["keysecret"]
        appKey = aliyundata[data]["appKey"]
        if data not in overstressing:
            aliyunqulityqueue.put(data)
        # 获取阿里云录音文件翻译的taskid
        task_id = file_translator_from_aliyun(accessKeySecret=accessKeySecret, accessKeyId=accessKeyId, appKey=appKey,
                                              file_link=file_link)
        return task_id
    except Exception as e:
        if data not in overstressing and data != 0:
            aliyunqulityqueue.put(data)
            qa_logger.error('error:%s %s', type(e), str(e))
        return ''
    finally:
        if data not in overstressing and data != 0:
            aliyunqulityqueue.put(data)


# 调用阿里云录音翻译
# @time_statistic(1,'task_id')
def aliyun_voice_translate(file_link, task_id, sample_id=''):
    """
    请求阿里云翻译服务进行翻译
    :param file_link: 待翻译的文件网络路径
    :param task_id: 任务ID
    :param sample_id: 任务中 单条录音的标识
    :return:
    """
    # fileLink = "https://zvoice.oss-cn-beijing.aliyuncs.com/rec/289/20200513/s120041301272475332746.wav"
    # 执行录音文件识别
    data = int(aliyunqulityqueue.get(timeout=5))
    try:
        accessKeyId = aliyundata[data]["keyid"]
        accessKeySecret = aliyundata[data]["keysecret"]
        appKey = aliyundata[data]["appKey"]
        if data not in overstressing:
            aliyunqulityqueue.put(data)
        # 获取阿里云录音文件翻译的taskid
        voice_task_id = file_translator_from_aliyun(
            accessKeyId, accessKeySecret, appKey, file_link)
        # 存储阿里云翻译返回的taskid
        qa_logger.info('task_id:%s sample_id:%s voice_task_id:%s',
                       task_id, sample_id, voice_task_id)
        if voice_task_id != '':
            updata_quality_voice_taskid(voice_taskid=voice_task_id, taskid=task_id, sampleid=sample_id,
                                        voice_result='', state=1)
            task_begin_datetime = time.strftime("%Y-%m-%d %H:%M:%S")
            memcachcon.set_cach_not_time('%sbegin_single_quality_task_begin%s' % (conn.basedbname, sample_id),
                                         task_begin_datetime)
            memcachcon.set_cach_not_time('%staskid%s%s' % (conn.basedbname, task_id, sample_id),
                                         {'accessKeyId': accessKeyId, 'accessKeySecret': accessKeySecret,
                                          'data': data, 'taskid': voice_task_id})
        else:
            updata_quality_voice_taskid(voice_taskid=voice_task_id, taskid=task_id, sampleid=sample_id,
                                        voice_result='', state=5)
    except Exception as e:
        if data not in overstressing and data != 0:
            aliyunqulityqueue.put(data)
        weixin_push(str(task_id), str(e), '智能质检aliyun_voice_translate')
        qa_logger.error('task_id:%s sample_id:%s error:%s %s',
                        task_id, sample_id, type(e), str(e))


# 录音翻译过期重新调用
def restart_translate(task_id, sample_id):
    # 查询文件地址
    quality_data_dict = get_task_single_quality_service_data(
        task_id=task_id, sample_id=sample_id)
    aliyun_voice_translate(quality_data_dict[0]["voxfile"], task_id, sample_id)


def begin_quality(task_id, quality_data, cmp_id, quality_t, user_id):
    try:
        # 查询要质检的数据c.voxfile,c.cause,s.sampleid,c.voice_taskid,c.voice_result
        # quality_data_dict = sql_voice_result(taskid)
        # for quality_data in quality_data_dict:
        # back_code = get_reault_voice_translate(quality_data['voice_taskid'], quality_data['sampleid'], taskid)
        # if back_code=='2':
        # quality_data_dict.append({'voxfile':quality_data['voxfile'],'sampleid':quality_data['sampleid'],
        #                           'saleid':quality_data['saleid'],'voice_taskid':quality_data['voice_taskid']})
        # l.ruleid 规则编码,l.weight规则权重,c.ctypeid规则类型(1:话术顺序2:问答类3:录音时长4:非正常挂机5:出现抢话6:语速过快7:静音),
        # c.role适用角色(1所有角色 2坐席 3客户),c.`range`检测范围 1全文 2指定范围,c.min_range最小范围,c.max_range最大范围,
        # c.content在ctypeid为1,2的时候使用 存内容,c.min_time在ctypeid为3的时候使用 最小录音时长,c.max_range最大录音时长,
        # c.close_time在ctypeid为4的时候使用 最后一句话到挂机时间间隔多少秒,c.over_num在ctypeid为5的时候使用 两段话重叠字数,
        # ,c.over_time在ctypeid为5的时候使用 两段话重叠时长,c.fast_num在ctypeid为6的时候使用 语速超过每分钟多少字,
        # c.fast_ignore在ctypeid为6的时候使用 每段语音少于多少字不检测,c.mute_time 在ctypeid为7的时候使用 静音时长大于多少秒,r.score
        # 查询质检规则
        # mute_score = 0 #静音得分
        # mute_lable = 0 #静音标签1very good 2good 3average 4poor 5verypoor
        # fast_score = 0 #语速得分
        # fast_lable = 0#语速标签1very good 2good 3average 4poor 5verypoor
        # calltime_score = 0 #录音时长得分
        # calltime_lable = 0#通话时长标签1very good 2good 3average 4poor 5verypoor
        # total_lable = 0#总得分标签 1very good 2good 3average 4poor 5verypoor
        total_score = 0  # 总得分
        # verbal_trick_score = 0 #话术得分
        # question_score = 0 #问题类得分
        # abnormality_score = 0#不正常挂机
        # forestall_score = 0 #抢话得分
        # 查询质检规则l.ruleid,l.weight,r.logic,r.score,r.is_send    logic 1满足所有条件 2满足其中一个条件 is_send0为不推送 1为推送
        # print(quality_da  ta['voice_result'])
        # is_hangoff  0不挂断 1挂断
        sample_id = quality_data['sampleid']
        cause = quality_data['cause']

        rules_list = sel_taskid_rules(task_id)
        if quality_t == 1 or quality_t == 3:
            del_quality_data(sample_id, task_id)
        voice_result = []
        if quality_data['voice_result']:
            voice_result = ast.literal_eval(quality_data['voice_result'])
        else:
            qa_logger.info('task_id:%s sample_id:%s', task_id, sample_id)
        is_hangoff = 0
        for rules in rules_list:
            rule_id = rules['ruleid']
            rules_score = rules['score']
            quality_rules_list = sql_rules_for_data(rule_id, task_id)
            # sel_score_data type 1结果标签 2语速统计 3静音时长统计 4录音时长统计
            is_match = 2
            is_sended = 1
            match = []
            individual_score = 0
            for quality_rules in quality_rules_list:
                match_data = 0
                # 规则类型(1:话术顺序2:问答类3:录音时长4:非正常挂机5:出现抢话6:语速过快7:静音)
                ctypeid = quality_rules['ctypeid']
                content = quality_rules['content']
                check_range = quality_rules['checkrange']
                rule_is_match = quality_rules['is_match']
                role = quality_rules['role']  # 适用角色(1所有角色 2坐席 3客户)

                max_range = quality_rules['max_range']  # 最大范围
                min_range = quality_rules['min_range']  # 最小范围

                min_time = quality_rules['min_time']
                max_time = quality_rules['max_time']
                close_time = quality_rules['close_time']
                over_time = quality_rules['over_time']

                over_num = quality_rules['over_num']
                word_num = quality_rules['word_num']
                word_range = quality_rules['word_range']
                fast_ignore = quality_rules['fast_ignore']
                fast_num = quality_rules['fast_num']
                mute_time = quality_rules['mute_time']
                if ctypeid == 1:
                    match_data = matching_rule_1(
                        content, rule_is_match, voice_result, task_id, sample_id)
                elif ctypeid == 2:
                    match_data = matching_rule_2(content, role, check_range, min_range, max_range, voice_result,
                                                 task_id, sample_id)
                elif ctypeid == 3:
                    match_data = matching_rule_3(
                        min_time, max_time, voice_result, task_id, sample_id)
                elif ctypeid == 4:
                    match_data = matching_rule_4(
                        role, close_time, voice_result, cause, task_id, sample_id)
                elif ctypeid == 5:
                    match_data = matching_rule_5(task_id, role, check_range, min_range, max_range, over_num, over_time,
                                                 voice_result, 1, sample_id)
                elif ctypeid == 6:
                    match_data = matching_rule_6(voice_result, fast_num, fast_ignore, role, check_range, min_range,
                                                 max_range, task_id, sample_id)
                elif ctypeid == 7:
                    match_data = matching_rule_7(role, check_range, min_range, max_range, mute_time, voice_result,
                                                 task_id, sample_id)
                elif ctypeid == 8:
                    match_data = matching_rule_8(content, role, check_range, min_range, max_range, voice_result,
                                                 task_id, word_num, word_range, sample_id)

                match.append(match_data)
            if match:
                logic = rules["logic"]
                if logic in (1, 2) and (1 in match or 2 not in match):
                    is_match = 1
                    if quality_t == 1:
                        individual_score = judge_score(rules["is_send"], rule_id, task_id, rules_score, rules['weight'],
                                                       user_id)
                    else:
                        # 查询是否已经命中过is_sended=2未命中
                        is_sended = sel_if_is_math(sample_id, rule_id, task_id)
                        if is_sended == 2:
                            if rules["is_hangoff"] == 1:
                                is_hangoff = 1
                                memcachcon.set_cach_not_time('{}is_hangoffsampleid{}'.format(
                                    conn.basedbname, sample_id), str(sample_id))
                            individual_score = judge_score(rules["is_send"], rule_id, task_id, rules_score,
                                                           rules['weight'],
                                                           user_id)

            # if is_match==1:#名字规则推送微信给java
            total_score += individual_score
            # 存储单项得分
            if quality_t == 1:
                insert_rule_score(rule_id, individual_score,
                                  sample_id, is_match, task_id)
            elif is_match == 1 and is_sended == 2:  # 判断是否已经触发过的规则，如果没触发就更新下触发状态
                update_is_math(individual_score, rule_id, sample_id, task_id)
        if quality_t == 1 or quality_t == 3:
            hangoff = 0
            if quality_t == 3:
                if memcachcon.if_exist('{}is_hangoffsampleid{}'.format(conn.basedbname, sample_id)) is not None:
                    hangoff = 1
            statistics_score(cmp_id, task_id, voice_result,
                             total_score, sample_id, 4, hangoff)
        updata_quality_voice_taskid('', task_id, sample_id, '', 4)
        return is_hangoff

    except Exception as e:
        qa_logger.error('task_id:%s quality_data:%s error:%s %s',
                        task_id, quality_data, type(e), str(e))
        weixin_push(str(task_id), str(e), '质检错误')
        return 0


# 开始质检规则
def begin_single_quality(task_id, quality_data, cmp_id, quality_t, user_id):
    """

    :param task_id: 任务编码
    :param quality_data: 检测数据
    :param cmp_id: 公司编码
    :param quality_t:
    :param user_id:
    :return:
    """
    try:
        # 查询要质检的数据c.voxfile,c.cause,s.sampleid,c.voice_taskid,c.voice_result
        # quality_data_dict = sql_voice_result(taskid)
        # for quality_data in quality_data_dict:
        # back_code = get_reault_voice_translate(quality_data['voice_taskid'], quality_data['sampleid'], taskid)
        # if back_code=='2':
        # quality_data_dict.append({'voxfile':quality_data['voxfile'],'sampleid':quality_data['sampleid'],
        #                           'saleid':quality_data['saleid'],'voice_taskid':quality_data['voice_taskid']})
        # l.ruleid 规则编码,l.weight规则权重,c.ctypeid规则类型(1:话术顺序2:问答类3:录音时长4:非正常挂机5:出现抢话6:语速过快7:静音),
        # c.role适用角色(1所有角色 2坐席 3客户),c.`range`检测范围 1全文 2指定范围,c.min_range最小范围,c.max_range最大范围,
        # c.content在ctypeid为1,2的时候使用 存内容,c.min_time在ctypeid为3的时候使用 最小录音时长,c.max_range最大录音时长,
        # c.close_time在ctypeid为4的时候使用 最后一句话到挂机时间间隔多少秒,c.over_num在ctypeid为5的时候使用 两段话重叠字数,
        # ,c.over_time在ctypeid为5的时候使用 两段话重叠时长,c.fast_num在ctypeid为6的时候使用 语速超过每分钟多少字,
        # c.fast_ignore在ctypeid为6的时候使用 每段语音少于多少字不检测,c.mute_time 在ctypeid为7的时候使用 静音时长大于多少秒,r.score
        # 查询质检规则
        # mute_score = 0 #静音得分
        # mute_lable = 0 #静音标签1very good 2good 3average 4poor 5verypoor
        # fast_score = 0 #语速得分
        # fast_lable = 0#语速标签1very good 2good 3average 4poor 5verypoor
        # calltime_score = 0 #录音时长得分
        # calltime_lable = 0#通话时长标签1very good 2good 3average 4poor 5verypoor
        # total_lable = 0#总得分标签 1very good 2good 3average 4poor 5verypoor
        total_score = 0  # 总得分
        # verbal_trick_score = 0 #话术得分
        # question_score = 0 #问题类得分
        # abnormality_score = 0#不正常挂机
        # forestall_score = 0 #抢话得分
        # 查询质检规则l.ruleid,l.weight,r.logic,r.score,r.is_send    logic 1满足所有条件 2满足其中一个条件 is_send0为不推送 1为推送
        # print(quality_da  ta['voice_result'])
        # is_hangoff  0不挂断 1挂断
        sample_id = quality_data['sampleid']
        cause = quality_data['cause']
        is_hangoff = 0  # 是否挂断电话 0不挂断 1挂断
        g_is_potential = 2  # 是否是意向客戶

        rules_list = sel_taskid_rules(task_id)
        if quality_t == 1 or quality_t == 3:
            del_quality_data(sample_id, task_id)
        voice_result = []
        if quality_data['voice_result']:
            voice_result = ast.literal_eval(quality_data['voice_result'])
        else:
            qa_logger.info('task_id:%s sample_id:%s', task_id, sample_id)
        for rules in rules_list:
            rule_id = rules['ruleid']  # 规则编码
            rules_score = rules['score']
            quality_rules_list = sql_rules_for_data(rule_id, task_id)
            # sel_score_data type 1结果标签 2语速统计 3静音时长统计 4录音时长统计
            # quality_rules_list = sql_quality_rules(task_id)
            # 删除之前质检的数据
            is_match = 2
            is_sended = 1
            match = []
            individual_score = 0
            is_potential = 2
            for quality_rules in quality_rules_list:
                match_data = 0
                # 规则类型(1:话术顺序2:问答类3:录音时长4:非正常挂机5:出现抢话6:语速过快7:静音)
                ctypeid = quality_rules['ctypeid']
                content = quality_rules['content']
                check_range = quality_rules['checkrange']
                rule_is_match = quality_rules['is_match']
                role = quality_rules['role']  # 适用角色(1所有角色 2坐席 3客户)

                max_range = quality_rules['max_range']  # 最大范围
                min_range = quality_rules['min_range']  # 最小范围

                min_time = quality_rules['min_time']
                max_time = quality_rules['max_time']
                close_time = quality_rules['close_time']
                over_time = quality_rules['over_time']

                over_num = quality_rules['over_num']
                word_num = quality_rules['word_num']
                word_range = quality_rules['word_range']
                fast_ignore = quality_rules['fast_ignore']
                fast_num = quality_rules['fast_num']
                mute_time = quality_rules['mute_time']

                if ctypeid == 1:
                    match_data = matching_rule_1(
                        content, rule_is_match, voice_result, task_id, sample_id)
                elif ctypeid == 2:
                    match_data = matching_rule_2(content, role, check_range, min_range, max_range, voice_result,
                                                 task_id, sample_id)
                elif ctypeid == 3:
                    match_data = matching_rule_3(
                        min_time, max_time, voice_result, task_id, sample_id)
                elif ctypeid == 4:
                    match_data = matching_rule_4(role, close_time, voice_result, cause, task_id, sample_id)
                elif ctypeid == 5:
                    match_data = matching_rule_5(task_id, role, check_range, min_range, max_range, over_num, over_time,
                                                 voice_result, 1, sample_id)
                elif ctypeid == 6:
                    match_data = matching_rule_6(voice_result, fast_num, fast_ignore, role, check_range, min_range,
                                                 max_range, task_id, sample_id)
                elif ctypeid == 7:
                    match_data = matching_rule_7(role, check_range, min_range, max_range, mute_time, voice_result,
                                                 task_id, sample_id)
                elif ctypeid == 8:
                    match_data = matching_rule_8(content, role, check_range, min_range, max_range, voice_result,
                                                 task_id, word_num, word_range, sample_id)
                match.append(match_data)
            if match:
                logic = rules["logic"]
                if logic in (1, 2) and (1 in match or 2 not in match):
                    is_match = 1
                    if quality_t == 1:
                        individual_score = judge_score(rules["is_send"], rule_id, task_id, rules_score, rules['weight'],
                                                       user_id)
                    else:
                        # 查询是否已经命中过is_sended=2未命中
                        is_sended = sel_if_is_math(sample_id, rule_id, task_id)
                        if is_sended == 2:
                            if rules["is_hangoff"] == 1:
                                is_hangoff = 1
                                memcachcon.set_cach_not_time('{}is_hangoffsampleid{}'.format(
                                    conn.basedbname, sample_id), str(sample_id))
                            individual_score = judge_score(rules["is_send"], rule_id, task_id, rules_score,
                                                           rules['weight'],
                                                           user_id)
            total_score += individual_score

            # 判断是否满足意向客户
            if is_match == 1:  # 命中
                is_potential = rules["is_potential"]
                if rules["is_potential"] == 1:
                    g_is_potential = 1
            else:  # 不命中
                is_potential = 2 if rules["is_potential"] == 1 else 1
                if is_potential == 1:
                    g_is_potential = 1
            # 存储单项得分
            if quality_t == 1:
                insert_rule_score(rule_id, individual_score,
                                  sample_id, is_match, task_id)
            elif is_match == 1 and is_sended == 2:  # 判断是否已经触发过的规则，如果没触发就更新下触发状态
                update_is_math(individual_score, rule_id, sample_id, task_id)
        if quality_t == 1 or quality_t == 3:
            hangoff = 0
            if quality_t == 3:
                if memcachcon.if_exist('{}is_hangoffsampleid{}'.format(conn.basedbname, sample_id)) is not None:
                    hangoff = 1
            statistics_score(cmp_id, task_id, voice_result, total_score,
                             sample_id, 4, hangoff, g_is_potential, '')
        return is_hangoff

    except Exception as e:
        qa_logger.error('task_id:%s quality_data:%s error:%s %s',
                        task_id, type(e), str(e))
        weixin_push(str(task_id), str(e), '质检错误')
        return 0


def judge_score(is_send, ruleid, taskid, score, weight, userid):
    individual_score = 0
    if is_send == 1:
        connect_java_port_target(ruleid, taskid, userid)
    if score < 0:
        individual_score = score
    else:
        individual_score = round(weight * score / 100, 2)
    return individual_score


# 调用java接口推送
def connect_java_port_target(ruleid, taskid, userid):
    try:
        url = "http://" + str(conn.java_targer) + "/sendGcAiWarnMsg_check?ruleid='" + str(
            ruleid) + "'&taskid='" + str(
            taskid) + "'&userid='" + str(userid) + "'"
        qa_logger.info('task_id:%s url:%s', taskid, url)
        req = rs.get(url, timeout=4)
        qa_logger.info('task_id:%s res:%s', taskid, req)
    except Exception as e:
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))


# 1结果标签 2语速统计 3静音时长统计 4录音时长统计
def statistics_score(cmpid, taskid, voice_result, total_score, sampleid, state, is_hangoff, g_is_potential=None,
                     voice_taskid=None):
    try:
        qa_logger.info('task_id:%s sample_id:%s cmpid:%s total_score:%s state:%s is_hangoff:%s',
                       taskid, sampleid, cmpid, total_score, state, is_hangoff)
        total_lable = 0
        mute_score = 0
        mute_lable = 0
        fast_lable = 0
        fast_score = 0
        calltime_lable = 0
        calltime_score = 0
        # 通话时长标签及值
        if voice_result:
            score_divide = sel_score_data(cmpid, 4, taskid)
            calltime_score = int(voice_result['BizDuration'] / 1000)
            # print('calltime_score',calltime_score,score_divide)
            qa_logger.info('task_id:%s sampleid:%s calltime_score:%s score_divide:%s',
                           taskid, sampleid, calltime_score, score_divide)
            calltime_lable = grade_divide(calltime_score, score_divide[0]['verygood_max'],
                                          score_divide[0]['verygood_min'],
                                          score_divide[0]['good_max'], score_divide[0]['good_min'],
                                          score_divide[0]['average_max'], score_divide[0]['average_max'],
                                          score_divide[0]['poor_max'], score_divide[0]['poor_min'],
                                          score_divide[0]['verypoor_max'], score_divide[0]['verypoor_min'], taskid)
            # 语速标签得分和值
            # print('55555555555')
            mute_score = average_speed(voice_result, 0, taskid)
            score_divide = sel_score_data(cmpid, 2, taskid)
            # print(mute_score,score_divide)
            mute_lable = grade_divide(mute_score, score_divide[0]['verygood_max'], score_divide[0]['verygood_min'],
                                      score_divide[0]['good_max'], score_divide[0]['good_min'],
                                      score_divide[0]['average_max'], score_divide[0]['average_max'],
                                      score_divide[0]['poor_max'], score_divide[0]['poor_min'],
                                      score_divide[0]['verypoor_max'], score_divide[0]['verypoor_min'], taskid)
            qa_logger.info('task_id:%s sampleid:%s mute_score:%s mute_lable:%s score_divide:%s',
                           taskid, sampleid, mute_score, mute_lable, score_divide)
            # 静音分值和等级
            fast_score = get_mute_time(voice_result, 0, taskid)
            score_divide = sel_score_data(cmpid, 3, taskid)
            fast_lable = grade_divide(fast_score, score_divide[0]['verygood_max'], score_divide[0]['verygood_min'],
                                      score_divide[0]['good_max'], score_divide[0]['good_min'],
                                      score_divide[0]['average_max'], score_divide[0]['average_max'],
                                      score_divide[0]['poor_max'], score_divide[0]['poor_min'],
                                      score_divide[0]['verypoor_max'], score_divide[0]['verypoor_min'], taskid)
            qa_logger.info('task_id:%s sampleid:%s fast_score:%s total_lable:%s score_divide:%s',
                           taskid, sampleid, fast_score, total_lable, score_divide)
            # 计算总分
            score_divide = sel_score_data(cmpid, 1, taskid)
            total_lable = grade_divide(total_score, score_divide[0]['verygood_max'],
                                       score_divide[0]['verygood_min'],
                                       score_divide[0]['good_max'], score_divide[0]['good_min'],
                                       score_divide[0]['average_max'], score_divide[0]['average_max'],
                                       score_divide[0]['poor_max'], score_divide[0]['poor_min'],
                                       score_divide[0]['verypoor_max'], score_divide[0]['verypoor_min'], taskid)
        qa_logger.info('task_id:%s sampleid:%s total_lable:%s score_divide:%s',
                       taskid, sampleid, total_lable, score_divide)
        # 存储质检结果
        if g_is_potential is None and voice_taskid is None:
            update_quality_result(total_score, total_lable, mute_score, mute_lable, fast_lable, fast_score,
                                  calltime_lable, calltime_score, sampleid, taskid, state, is_hangoff)
        else:
            update_single_quality_result(total_score, total_lable, mute_score, mute_lable, fast_lable, fast_score,
                                         calltime_lable, calltime_score, sampleid, taskid, state, is_hangoff,
                                         g_is_potential, str(voice_result), voice_taskid)
        billing(taskid, cmpid, calltime_score, sampleid)
    except Exception as e:
        weixin_push(str(taskid), str(e), '质检错误statistics_score')
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))


# 匹配ctype=1的规则(话术顺序)
# @time_statistic(3,'taskid')
def matching_rule_1(content, match, voice_result, taskid, sampleid):
    is_match = 2  # 1:命中2：未命中
    # match 1满足 2不满足
    # s#话术1@s#话术2
    qa_logger.info('task_id:%s sampleid:%s content:%s match:%s voice_result:%s',
                   taskid, sampleid, content, match, voice_result)
    try:
        verbal = ''
        # content = '@'+content
        worklist = 0
        pipe_word_split = content.split("@")  # ['s#陈涛', 'c#你是谁']
        Sentences = voice_result['Result']['Sentences']
        qa_logger.info('task_id:%s sampleid:%s pipe_word_split:%s', taskid, sampleid, pipe_word_split)
        if pipe_word_split and Sentences:
            for i, data in enumerate(Sentences):
                qa_logger.info('task_id:%s sampleid:%s i:%s data:%s', taskid, sampleid, i, data)
                Sentences_data_num = -1
                chatting = 0
                for j, text in enumerate(pipe_word_split):
                    qa_logger.info('task_id:%s sampleid:%s j:%s text:%s', taskid, sampleid, j, text)
                    bidding_list = []
                    if Sentences_data_num != -1:
                        qa_logger.info('Sentences_data_num != -1 task_id:%s sampleid:%s Sentences_data_num:%s len(Sentences):%s',
                                       taskid, sampleid, Sentences_data_num, len(Sentences))
                        if len(Sentences) > Sentences_data_num + 1:
                            chatting_data = Sentences[Sentences_data_num + 1]["Text"]
                            text_re = text[2:]
                            channel = text[:1]
                            channel_next = Sentences[Sentences_data_num +
                                                     1]["ChannelId"]
                            if (channel == 's' and channel_next == 1) or (channel == 'c' and channel_next == 0):
                                pipe_word = re.compile(text_re)
                                bidding_list = re.findall(
                                    pipe_word, chatting_data)
                            qa_logger.info('task_id:%s sampleid:%s chatting_data:%s channel:%s channel_next:%s text_re:%s bidding_list:%s Sentences_data_num:%s',
                                           taskid, sampleid, chatting_data, channel, channel_next, text_re, bidding_list, Sentences_data_num)
                        if len(bidding_list) != 0:
                            Sentences_data_num = Sentences_data_num + 1
                            chatting = 1
                        else:
                            chatting = 0
                            Sentences_data_num = -1
                            break
                    else:
                        chatting_data = data["Text"]
                        text_re = text[2:]
                        channel = text[:1]
                        if (channel == 's' and data["ChannelId"] == 1) or (
                                channel == 'c' and data["ChannelId"] == 0):
                            pipe_word = re.compile(text_re)
                            bidding_list = re.findall(pipe_word, chatting_data)
                        qa_logger.info('task_id:%s sampleid:%s data["Text"]:%s channel:%s data["ChannelId"]:%s text_re:%s bidding_list:%s Sentences_data_num:%s',
                                       taskid, sampleid, data["Text"], channel, data["ChannelId"], text_re, bidding_list, Sentences_data_num)
                        if len(bidding_list) != 0:
                            Sentences_data_num = i
                            chatting = 1
                        else:
                            Sentences_data_num = -1
                            chatting = 0
                            break
                if chatting == 1:
                    worklist = 1
                    break
        if worklist == 1 and match == 1:
            is_match = 1
        if worklist == 0 and match == 2:
            is_match = 1
        qa_logger.info('task_id:%s sampleid:%s content:%s verbal:%s is_match:%s',
                       taskid, sampleid, content, verbal, is_match)
        return is_match
    except Exception as e:
        weixin_push(str(taskid) + " " + str(sampleid), str(e), '质检错误matching_rule_1')
        qa_logger.error('task_id:%s content:%s error:%s %s',
                        taskid, content, type(e), str(e))
        return is_match


# 匹配ctype=2的规则(问答类)
# @time_statistic(6, 'taskid')
def matching_rule_2(content, role, range, min_range, max_range, voice_result, taskid, sampleid):
    is_match = 2  # 1:命中2：未命中
    # range
    qa_logger.info('task_id:%s content:%s verbal:%s is_match:%s', taskid,
                   content, role, range, min_range, max_range, voice_result)

    try:
        verbal = ''
        qa_logger.info('task_id:%s sampleid:%s content:%s role:%s is_match:%s min_range:%s max_range:%s voice_result:%s',
                       taskid, sampleid, content, role, is_match, min_range, max_range, voice_result)
        questionlist = []
        for contentlist in content.split('@'):
            questionlist.append(contentlist)
            print('questionlist', questionlist)

        if voice_result:
            for i, data in enumerate(voice_result['Result']['Sentences']):
                # print(i,data)
                if len(questionlist) > 0:
                    text_content = questionlist[0].split('#')
                    text_content_client = text_content[0]
                    text_content_text = str(text_content[1])
                    print(text_content, text_content_client,
                          data['ChannelId'], text_content_text, data['Text'])
                    # print()
                    if range == 2:
                        if min_range and max_range and min_range <= i + 1 <= max_range:
                            # print(min_range,max_range,(i+1))
                            if data['ChannelId'] == 1 and text_content_client == 's':  # 客服
                                pipe_word = re.compile(text_content_text)
                                worklist = re.findall(pipe_word, data['Text'])
                                if len(worklist) != 0:
                                    questionlist.remove(questionlist[0])

                            elif data['ChannelId'] == 0 and text_content_client == 'c':  # 客户
                                pipe_word = re.compile(text_content_text)
                                worklist = re.findall(pipe_word, data['Text'])
                                if len(worklist) != 0:
                                    questionlist.remove(questionlist[0])
                        elif min_range and min_range <= i + 1 and max_range == None:
                            # print('3',min_range, max_range, (i + 1))
                            if data['ChannelId'] == 0 and text_content_client == 'c':  # 客户
                                pipe_word = re.compile(text_content_text)
                                worklist = re.findall(pipe_word, data['Text'])
                                if len(worklist) != 0:
                                    questionlist.remove(questionlist[0])
                                # channel_1 = channel_1 +  'c#' + data['Text']
                            elif data['ChannelId'] == 1 and text_content_client == 's':  # 客服
                                pipe_word = re.compile(text_content_text)
                                worklist = re.findall(pipe_word, data['Text'])
                                if len(worklist) != 0:
                                    questionlist.remove(questionlist[0])
                        elif max_range and max_range >= i + 1 and min_range == None:
                            # print('2',min_range, max_range, (i + 1))
                            if data['ChannelId'] == 1 and text_content_client == 's':  # 客服
                                pipe_word = re.compile(text_content_text)
                                worklist = re.findall(pipe_word, data['Text'])
                                if len(worklist) != 0:
                                    questionlist.remove(questionlist[0])
                                # channel_1 = channel_1 +  'c#' + data['Text']
                            elif data['ChannelId'] == 0 and text_content_client == 'c':  # 客户
                                pipe_word = re.compile(text_content_text)
                                worklist = re.findall(pipe_word, data['Text'])
                                if len(worklist) != 0:
                                    questionlist.remove(questionlist[0])
                    else:
                        # print(type(data['ChannelId']),data['ChannelId'])
                        if data['ChannelId'] == 1 and text_content_client == 's':  # 客服
                            pipe_word = re.compile(text_content_text)
                            worklist = re.findall(pipe_word, data['Text'])
                            if len(worklist) != 0:
                                questionlist.remove(questionlist[0])
                            # channel_1 = channel_1 +  'c#' + data['Text']
                        elif data['ChannelId'] == 0 and text_content_client == 'c':  # 客户
                            print('开始开始')
                            pipe_word = re.compile(text_content_text)
                            worklist = re.findall(pipe_word, data['Text'])
                            if len(worklist) != 0:
                                questionlist.remove(questionlist[0])

            if len(questionlist) == 0:
                is_match = 1
            qa_logger.info('task_id:%s content:%s', taskid, content)
        return is_match
    except Exception as e:
        weixin_push(str(taskid) + " " + str(sampleid),
                    str(e), '质检错误matching_rule_2')
        qa_logger.error('task_id:%s content:%s error:%s %s',
                        taskid, content, type(e), str(e))
        return is_match


# 匹配ctype=2的规则(关键字)
def matching_rule_8(content, role, range, min_range, max_range, voice_result, taskid, word_num, word_range, sampleid):
    is_match = 2  # 1:命中2：未命中
    # range
    print(content, role, range, min_range, max_range, voice_result)
    try:  # role1所有角色 2坐席 3客户
        verbal = []
        # channel_0 = '' #客服说的话
        # channel_1 = ''  # 客户说的话
        qa_logger.info('task_id:%s sampleid:%s content:%s role:%s is_match:%s min_range:%s max_range:%s voice_result:%s',
                       taskid, sampleid, content, role, is_match, min_range, max_range, voice_result)
        datanum = 0
        wordnum = 0
        if word_num:
            word_num = 1
        if word_range:
            word_range = 0
        if voice_result:
            for i, data in enumerate(voice_result['Result']['Sentences']):
                if range == 1:
                    if role == 1:  # 全部：
                        verbal.append(data['Text'])
                    elif data['ChannelId'] == 0 and role == 3:  # 客户
                        verbal.append(data['Text'])
                    elif data['ChannelId'] == 1 and role == 2:  # 客服
                        verbal.append(data['Text'])
                elif range == 2:
                    if role == 1:  # 全部：
                        datanum += 1
                        if min_range != None and max_range != None and min_range <= datanum <= max_range:
                            verbal.append(data['Text'])
                        elif min_range != None and min_range <= datanum and max_range == None:
                            verbal.append(data['Text'])
                        elif max_range != None and max_range >= datanum and min_range == None:
                            verbal.append(data['Text'])
                    elif data['ChannelId'] == 0 and role == 3:  # 客户
                        datanum += 1
                        if min_range != None and max_range != None and min_range <= datanum <= max_range:
                            verbal.append(data['Text'])
                        elif min_range != None and min_range <= datanum and max_range == None:
                            verbal.append(data['Text'])
                        elif max_range != None and max_range >= datanum and min_range == None:
                            verbal.append(data['Text'])
                    elif data['ChannelId'] == 1 and role == 2:  # 客服
                        datanum += 1
                        if min_range != None and max_range != None and min_range <= datanum <= max_range:
                            verbal.append(data['Text'])
                        elif min_range != None and min_range <= datanum and max_range == None:
                            verbal.append(data['Text'])
                        elif max_range != None and max_range >= datanum and min_range == None:
                            verbal.append(data['Text'])
            qa_logger.info('task_id:%s sampleid:%s content:%s',
                           taskid, sampleid, content)
            for data in verbal:
                print('verbal', data, content)
                content = content.replace("@", "|")
                print('verbal', data, content)
                pipe_word = re.compile(content)
                worklist = re.findall(pipe_word, data)
                if len(worklist) != 0:
                    wordnum += 1
                    is_match = 1

        # if word_range==1 and wordnum>=word_num:
        #     is_match = 1
        # elif word_range==2 and wordnum<word_num:
        #     is_match = 1
        return is_match
    except Exception as e:
        weixin_push(str(taskid) + " " + str(sampleid),
                    str(e), '质检错误matching_rule_8')
        qa_logger.error('task_id:%s content:%s error:%s %s',
                        taskid, content, type(e), str(e))
        return is_match


# matching_rule_2("c#你是机器人吗@s#我是跃讯机器人",1,1,None,None,{'TaskId': '9edf0d75a70311ea954a63b51b005f56', 'RequestId': '524A7980-A5ED-4FCD-981C-AE3CADD53341', 'StatusText': 'SUCCESS', 'BizDuration': 15860, 'SolveTime': 1591344460164, 'StatusCode': 21050000, 'Result': {'Words': [{'Word': '喂', 'EndTime': 330, 'BeginTime': 150, 'ChannelId': 0}, {'Word': '喂喂', 'EndTime': 660, 'BeginTime': 330, 'ChannelId': 0}, {'Word': '喂', 'EndTime': 790, 'BeginTime': 610, 'ChannelId': 1}, {'Word': '喂', 'EndTime': 810, 'BeginTime': 660, 'ChannelId': 0}, {'Word': '你好', 'EndTime': 1330, 'BeginTime': 790, 'ChannelId': 1}, {'Word': '你好', 'EndTime': 1110, 'BeginTime': 810, 'ChannelId': 0}, {'Word': '喂', 'EndTime': 1260, 'BeginTime': 1110, 'ChannelId': 0}, {'Word': '喂喂', 'EndTime': 1590, 'BeginTime': 1260, 'ChannelId': 0}, {'Word': '你好', 'EndTime': 1710, 'BeginTime': 1590, 'ChannelId': 0}, {'Word': '喂', 'EndTime': 2980, 'BeginTime': 2860, 'ChannelId': 0}, {'Word': '你好', 'EndTime': 3400, 'BeginTime': 2980, 'ChannelId': 0}, {'Word': '哎', 'EndTime': 3490, 'BeginTime': 3310, 'ChannelId': 1}, {'Word': '喂', 'EndTime': 3550, 'BeginTime': 3400, 'ChannelId': 0}, {'Word': '你好', 'EndTime': 4030, 'BeginTime': 3490, 'ChannelId': 1}, {'Word': '你好', 'EndTime': 3910, 'BeginTime': 3550, 'ChannelId': 0}, {'Word': '喂', 'EndTime': 4030, 'BeginTime': 3910, 'ChannelId': 0}, {'Word': '你好', 'EndTime': 4300, 'BeginTime': 4030, 'ChannelId': 0}, {'Word': '我', 'EndTime': 4150, 'BeginTime': 4030, 'ChannelId': 1}, {'Word': '是', 'EndTime': 4270, 'BeginTime': 4150, 'ChannelId': 1}, {'Word': '大白', 'EndTime': 4570, 'BeginTime': 4270, 'ChannelId': 1}, {'Word': '教育', 'EndTime': 4780, 'BeginTime': 4570, 'ChannelId': 1}, {'Word': '的', 'EndTime': 4900, 'BeginTime': 4780, 'ChannelId': 1}, {'Word': '李', 'EndTime': 5050, 'BeginTime': 4900, 'ChannelId': 1}, {'Word': '老师', 'EndTime': 5830, 'BeginTime': 5050, 'ChannelId': 1}, {'Word': '不用', 'EndTime': 6140, 'BeginTime': 5810, 'ChannelId': 0}, {'Word': '啊', 'EndTime': 6100, 'BeginTime': 5830, 'ChannelId': 1}, {'Word': '今年', 'EndTime': 6370, 'BeginTime': 6100, 'ChannelId': 1}, {'Word': '不用', 'EndTime': 6440, 'BeginTime': 6140, 'ChannelId': 0}, {'Word': '暑假', 'EndTime': 6700, 'BeginTime': 6370, 'ChannelId': 1}, {'Word': '不用', 'EndTime': 6770, 'BeginTime': 6440, 'ChannelId': 0}, {'Word': '呀', 'EndTime': 6880, 'BeginTime': 6700, 'ChannelId': 1}, {'Word': '不用', 'EndTime': 7130, 'BeginTime': 6770, 'ChannelId': 0}, {'Word': '我们', 'EndTime': 7120, 'BeginTime': 6880, 'ChannelId': 1}, {'Word': '在', 'EndTime': 7270, 'BeginTime': 7120, 'ChannelId': 1}, {'Word': '不', 'EndTime': 7310, 'BeginTime': 7130, 'ChannelId': 0}, {'Word': '南城', 'EndTime': 7690, 'BeginTime': 7270, 'ChannelId': 1}, {'Word': '需要', 'EndTime': 7550, 'BeginTime': 7310, 'ChannelId': 0}, {'Word': '不', 'EndTime': 7700, 'BeginTime': 7550, 'ChannelId': 0}, {'Word': '呢', 'EndTime': 7900, 'BeginTime': 7690, 'ChannelId': 1}, {'Word': '需要', 'EndTime': 7940, 'BeginTime': 7700, 'ChannelId': 0}, {'Word': '是', 'EndTime': 8110, 'BeginTime': 7900, 'ChannelId': 1}, {'Word': '不', 'EndTime': 8090, 'BeginTime': 7940, 'ChannelId': 0}, {'Word': '需要', 'EndTime': 8330, 'BeginTime': 8090, 'ChannelId': 0}, {'Word': '开设', 'EndTime': 8380, 'BeginTime': 8110, 'ChannelId': 1}, {'Word': '不', 'EndTime': 8480, 'BeginTime': 8330, 'ChannelId': 0}, {'Word': '了', 'EndTime': 8500, 'BeginTime': 8380, 'ChannelId': 1}, {'Word': '需要', 'EndTime': 8750, 'BeginTime': 8480, 'ChannelId': 0}, {'Word': '一个', 'EndTime': 8770, 'BeginTime': 8500, 'ChannelId': 1}, {'Word': '不', 'EndTime': 8870, 'BeginTime': 8750, 'ChannelId': 0}, {'Word': '新', 'EndTime': 8920, 'BeginTime': 8770, 'ChannelId': 1}, {'Word': '需要', 'EndTime': 9140, 'BeginTime': 8870, 'ChannelId': 0}, {'Word': '校区', 'EndTime': 9640, 'BeginTime': 8920, 'ChannelId': 1}, {'Word': '不', 'EndTime': 9290, 'BeginTime': 9140, 'ChannelId': 0}, {'Word': '需要', 'EndTime': 9470, 'BeginTime': 9290, 'ChannelId': 0}, {'Word': '啊', 'EndTime': 9650, 'BeginTime': 9470, 'ChannelId': 0}, {'Word': '可以', 'EndTime': 9940, 'BeginTime': 9640, 'ChannelId': 1}, {'Word': '不', 'EndTime': 9770, 'BeginTime': 9650, 'ChannelId': 0}, {'Word': '需要', 'EndTime': 10010, 'BeginTime': 9770, 'ChannelId': 0}, {'Word': '免费', 'EndTime': 10330, 'BeginTime': 9940, 'ChannelId': 1}, {'Word': '不要', 'EndTime': 10310, 'BeginTime': 10010, 'ChannelId': 0}, {'Word': '不要', 'EndTime': 10640, 'BeginTime': 10310, 'ChannelId': 0}, {'Word': '赠送', 'EndTime': 10750, 'BeginTime': 10330, 'ChannelId': 1}, {'Word': '不要', 'EndTime': 10880, 'BeginTime': 10640, 'ChannelId': 0}, {'Word': '二十', 'EndTime': 11050, 'BeginTime': 10750, 'ChannelId': 1}, {'Word': '不要', 'EndTime': 11210, 'BeginTime': 10880, 'ChannelId': 0}, {'Word': '个', 'EndTime': 11230, 'BeginTime': 11050, 'ChannelId': 1}, {'Word': '不要', 'EndTime': 11480, 'BeginTime': 11210, 'ChannelId': 0}, {'Word': '小时', 'EndTime': 11650, 'BeginTime': 11230, 'ChannelId': 1}, {'Word': '不要', 'EndTime': 11780, 'BeginTime': 11480, 'ChannelId': 0}, {'Word': '一对一', 'EndTime': 11980, 'BeginTime': 11650, 'ChannelId': 1}, {'Word': '不要', 'EndTime': 12080, 'BeginTime': 11780, 'ChannelId': 0}, {'Word': '的', 'EndTime': 12130, 'BeginTime': 11980, 'ChannelId': 1}, {'Word': '不要', 'EndTime': 12290, 'BeginTime': 12080, 'ChannelId': 0}, {'Word': '课程', 'EndTime': 12850, 'BeginTime': 12130, 'ChannelId': 1}, {'Word': '不要', 'EndTime': 12410, 'BeginTime': 12290, 'ChannelId': 0}, {'Word': '可以', 'EndTime': 13030, 'BeginTime': 12850, 'ChannelId': 1}, {'Word': '帮助', 'EndTime': 13270, 'BeginTime': 13030, 'ChannelId': 1}, {'Word': '您', 'EndTime': 13390, 'BeginTime': 13270, 'ChannelId': 1}, {'Word': '的', 'EndTime': 13540, 'BeginTime': 13390, 'ChannelId': 1}, {'Word': '孩子', 'EndTime': 13960, 'BeginTime': 13540, 'ChannelId': 1}, {'Word': '高效', 'EndTime': 14260, 'BeginTime': 13960, 'ChannelId': 1}, {'Word': '的', 'EndTime': 14410, 'BeginTime': 14260, 'ChannelId': 1}, {'Word': '提高', 'EndTime': 14620, 'BeginTime': 14410, 'ChannelId': 1}, {'Word': '您好', 'EndTime': 15600, 'BeginTime': 15270, 'ChannelId': 1}, {'Word': '家长', 'EndTime': 15750, 'BeginTime': 15600, 'ChannelId': 1}], 'Sentences': [{'EndTime': 2170, 'SilenceDuration': 0, 'BeginTime': 0, 'Text': '喂喂喂喂你好喂喂喂你好。', 'ChannelId': 0, 'SpeechRate': 304, 'EmotionValue': 5.7}, {'EndTime': 1530, 'SilenceDuration': 0, 'BeginTime': 250, 'Text': '喂，你好。', 'ChannelId': 1, 'SpeechRate': 140, 'EmotionValue': 6.4}, {'EndTime': 4580, 'SilenceDuration': 0, 'BeginTime': 2590, 'Text': '喂，你好喂你好喂，你好。', 'ChannelId': 0, 'SpeechRate': 271, 'EmotionValue': 5.5}, {'EndTime': 14940, 'SilenceDuration': 0, 'BeginTime': 3010, 'Text': '哎，你好，我是大白教育的李老师啊。今年暑假呀，我们在南城呢是开设了一个新校区，可以免费赠送20个小时一对一的课程，可以帮助您的孩子高效的提高。', 'ChannelId': 1, 'SpeechRate': 321, 'EmotionValue': 6.2}, {'EndTime': 12790, 'SilenceDuration': 0, 'BeginTime': 5540, 'Text': '不用不用不用不用不需要不需要不需要不需要不需要不需要啊不需要不要不要不要不要不要不要不要不要不要。', 'ChannelId': 0, 'SpeechRate': 397, 'EmotionValue': 5.6}, {'EndTime': 15840, 'SilenceDuration': 2, 'BeginTime': 15030, 'Text': '您好，家长。', 'ChannelId': 1, 'SpeechRate': 296, 'EmotionValue': 6.4}]}},903)
# 统计客服说的平均语速
def average_speed(voice_result, channel, taskid):
    speech = 0
    i = 0
    average = 0
    try:
        if voice_result:
            for data in voice_result['Result']['Sentences']:
                if data['ChannelId'] == channel:
                    speech += data['SpeechRate']
                    i += 1
            if i == 0:
                average = 0
            else:
                average = int(float(speech) / float(i))
        return average
    except Exception as e:
        weixin_push(str(taskid), str(e), '质检错误average_speed')
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))
        return average


# 质检等级划分
def grade_divide(score, verygood_max, verygood_min, good_max, good_min, average_max, average_min, poor_max,
                 poor_min,
                 verypoor_max, verypoor_min, taskid):
    # print(score,verygood_max,verygood_min,good_max,good_min,average_max,average_min,poor_max,poor_min,verypoor_max,verypoor_min)
    the_dicide = 0
    try:
        print((score, verygood_max, verygood_min, good_max, good_min, average_max, average_min, poor_max, poor_min,
               verypoor_max, verypoor_min, taskid))
        print(float(good_min), float(score), float(good_max))
        if float(verygood_min) <= float(score) <= float(verygood_max):
            the_dicide = 1

        elif float(good_min) <= float(score) <= float(good_max):
            the_dicide = 2
            print('dddddd', the_dicide)
        elif float(average_min) <= float(score) <= float(average_max):
            the_dicide = 3
        elif float(poor_min) <= float(score) <= float(poor_max):
            the_dicide = 4
        # elif verypoor_min!='' and verypoor_max!='':
        elif float(verypoor_min) <= float(score) <= float(verypoor_max):
            the_dicide = 5
        print('the_dicide', the_dicide)
        return the_dicide
    except Exception as e:
        print(e)
        weixin_push(str(taskid), str(e), '质检错误grade_divide')
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))
        return the_dicide


# 匹配ctype=3的规则(录音时长)
def matching_rule_3(min_time, max_time, voice_result, taskid, sampleid):
    is_match = 2  # 1:命中2：未命中
    print(min_time, max_time)
    print('ggggggggggggggg', min_time, max_time, voice_result, taskid)
    try:
        if voice_result:
            print('fffsssss', min_time, max_time)
            if min_time != None and min_time != 0 and max_time != None and max_time != 0:
                print('eesssssssss', float(min_time), float(
                    voice_result['BizDuration'] / 1000), float(max_time))
                if float(min_time) < float(voice_result['BizDuration'] / 1000) < float(max_time):
                    is_match = 1
            elif min_time != None and min_time != 0 and (max_time == None or max_time == 0):
                print(333333, voice_result['BizDuration'] / 1000)
                if float(min_time) <= float(voice_result['BizDuration'] / 1000):
                    is_match = 1
            elif max_time != None and max_time != 0 and (min_time == None or min_time == 0):
                print(555555555)
                if float(max_time) >= float(voice_result['BizDuration'] / 1000):
                    is_match = 1
        print(568878)
        return is_match
    except Exception as e:
        print(" matching_rule_3 ", e)
        weixin_push(str(taskid) + " " + str(sampleid),
                    str(e), '质检错误matching_rule_3')
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))
        return is_match


# 匹配ctype=4的规则(非正常挂机)
def matching_rule_4(role, close_time, voice_result, close_man, taskid, sampleid):
    # role 1所有角色 2坐席 3客户   close_man 0客户断开 1坐席断开
    is_match = 2
    print('matching_rule_4', role, close_time, voice_result, close_man)
    try:
        if voice_result:
            pause_time = 0
            all_time = voice_result['BizDuration']
            Sentences_list = voice_result["Result"]['Sentences']
            people = 0

            for Sentences in Sentences_list:
                print(type(Sentences['EndTime']), type(pause_time), Sentences["ChannelId"], role, all_time,
                      Sentences["Text"])
                if role == 1:
                    print(111111)
                    if Sentences['EndTime'] > pause_time:
                        pause_time = Sentences['EndTime']
                        people = Sentences["ChannelId"]  # people1是客户 0 是客服
                elif role == 2 and Sentences["ChannelId"] == 1:
                    print(2222222222)
                    if Sentences['EndTime'] > pause_time:
                        pause_time = Sentences['EndTime']
                        people = Sentences["ChannelId"]  # people1是客户 0 是客服
                elif role == 3 and Sentences["ChannelId"] == 0:
                    print(33333333)
                    if Sentences['EndTime'] > pause_time:
                        print('eddd', Sentences['EndTime'], pause_time)
                        pause_time = Sentences['EndTime']
                        people = Sentences["ChannelId"]  # people1是客户 0 是客服
            difference_time = (all_time - pause_time) / 1000
            print('difference_time', difference_time, close_time, pause_time)
            if float(difference_time) > float(close_time):
                is_match = 1
            qa_logger.info('task_id:%s sampleid:%s difference_time:%s close_time:%s role:%s people:%s close_man:%s',
                           taskid, sampleid, difference_time, close_time, role, people, close_man)
        return is_match
    except Exception as e:
        weixin_push(str(taskid) + " " + str(sampleid),
                    str(e), '质检错误matching_rule_4')
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))
        return is_match


# 匹配ctype=5的规则(出现抢话) #字数要大于不等于
def matching_rule_5(taskid, role, range, min_range, max_range, over_num, over_time, voice_result, the_man, sampleid):
    is_match = 2  # 1:命中2：未命中  role 1所有角色 2坐席 3客户
    try:
        text_range = []
        if voice_result:
            Sentences_list = voice_result['Result']['Sentences']
            datanum = 0
            for i, Sentences in enumerate(Sentences_list):
                print(i, Sentences)
                text_range.append({'BeginTime': Sentences['BeginTime'], 'Text': Sentences['Text'],
                                   'ChannelId': Sentences['ChannelId'], 'EndTime': Sentences['EndTime']})

            min_time = 0  # 开始时间
            max_time = 0  # 结束时间
            before_text = ''
            text_time = []
            text_num = []
            channel = []
            print('text_range', text_range)
            for i, text_data in enumerate(text_range):
                the_text = re.sub(
                    "[\s+\.\!\/_,$%^*(+\"\']+|[+——！，。？、~@#￥%……&*（）]+", "", str(text_data['Text']))
                print(len(the_text), the_text)
                if i != 0:
                    if max_time > text_data['BeginTime'] and text_data['EndTime'] <= max_time:
                        print(111111, the_text,
                              float(int(text_data['EndTime']) -
                                    int(text_data['BeginTime'])) / 1000,
                              text_data['ChannelId'])
                        text_num.append(len(the_text))
                        text_time.append(
                            float(int(text_data['EndTime']) - int(text_data['BeginTime'])) / 1000)
                        channel.append(text_data['ChannelId'])
                    elif max_time > text_data['BeginTime'] and text_data['EndTime'] >= max_time:
                        print(max_time, text_data['BeginTime'], 22222222)
                        all_time = float(
                            (int(max_time) - int(text_data['BeginTime'])) / 1000)
                        text_time.append(all_time)
                        channel.append(text_data['ChannelId'])
                        forestall_time = float(
                            (int(text_data['EndTime']) - int(text_data['BeginTime'])) / 1000)
                        forestall_time_before = float(
                            (max_time - min_time) / 1000)
                        print('forestall_time', forestall_time, forestall_time_before, len(the_text),
                              len(before_text))
                        if forestall_time != 0:
                            ch_text_num = float(
                                len(the_text) * all_time) / forestall_time
                            if len(before_text) < len(the_text):
                                # text_num.append((len(before_text) / forestall_time) * all_time)
                                if len(before_text) < int(ch_text_num):
                                    text_num.append(len(before_text))
                                else:
                                    text_num.append(ch_text_num)
                            else:
                                text_num.append(ch_text_num)
                        else:
                            text_num.append(0)
                min_time = text_data['BeginTime']
                max_time = text_data['EndTime']
                before_text = the_text
            print('sssssTTT', text_time, text_num, channel)
            for i, num in enumerate(text_num):
                if role == 1:  # role 1所有角色 2坐席 3客户
                    if over_num != None and over_time != None:
                        if text_time[i] > over_time and text_num[i] > over_num:
                            is_match = 1
                    elif over_num != None and over_time == None:
                        if text_num[i] > over_num:
                            is_match = 1
                    elif over_num == None and over_time != None:
                        if text_time[i] > over_time:
                            is_match = 1
                else:  # 坐席
                    if over_num != None and over_time != None:
                        print(text_time[i], over_time,
                              text_num[i], over_num, channel[i], role)
                        if text_time[i] > over_time and text_num[i] > over_num and (
                                (channel[i] == 0 and role == 3) or (channel[i] == 1 and role == 2)):
                            is_match = 1
                    elif over_num != None and over_time == None and (
                            (channel[i] == 0 and role == 3) or (channel[i] == 1 and role == 2)):
                        if text_num[i] > over_num:
                            is_match = 1
                    elif over_num == None and over_time != None and (
                            (channel[i] == 0 and role == 3) or (channel[i] == 1 and role == 2)):
                        if text_time[i] > over_time:
                            is_match = 1
            qa_logger.info('task_id:%s sampleid:%s text_time:%s text_num:%s role:%s channel:%s is_match:%s over_num:%s over_time:%s',
                           taskid, sampleid, text_time, text_num, role, channel, is_match, over_num, over_time)
        return is_match
    except Exception as e:
        weixin_push(str(taskid) + " " + str(sampleid),
                    str(e), '质检错误matching_rule_5')
        qa_logger.error('task_id:%s sampleid:%s error:%s %s',
                        taskid, sampleid, type(e), str(e))
        return is_match


#
def get_result_matching_rule_6(fast_ignore, fast_num, role, the_text, Sentences, taskid):
    is_match = 2
    try:
        if fast_ignore != None and fast_num != None:
            print('333333333333')
            if len(the_text) >= fast_ignore and int(Sentences['SpeechRate']) > fast_num:
                if role == 1:
                    is_match = 1
                elif role == 2 and Sentences['ChannelId'] == 1:  # 客服
                    is_match = 1
                elif role == 3 and Sentences['ChannelId'] == 0:  # 客户
                    is_match = 1
        elif fast_ignore != None and fast_num == None:
            print('44444444444444')
            if len(the_text) >= fast_ignore:
                if role == 1:
                    is_match = 1
                elif role == 2 and Sentences['ChannelId'] == 1:  # 客服
                    is_match = 1
                elif role == 3 and Sentences['ChannelId'] == 0:  # 客户
                    is_match = 1
        elif fast_num != None and fast_ignore == None:
            print('5555555555555')
            if int(Sentences['SpeechRate']) > fast_num:
                if role == 1:
                    is_match = 1
                elif role == 2 and Sentences['ChannelId'] == 1:  # 客服
                    is_match = 1
                elif role == 3 and Sentences['ChannelId'] == 0:  # 客户
                    is_match = 1
        print('get_result_matching_rule_6', is_match, fast_ignore,
              fast_num, len(the_text), Sentences['SpeechRate'])
        return is_match
    except Exception as e:
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))
        return is_match


def get_rang_matching_rule_6(min_rang, max_range, datanum, fast_ignore, fast_num, role, the_text, Sentences,
                             taskid):
    is_match = 2
    try:
        if min_rang != None and max_range != None and min_rang <= datanum <= max_range:
            print('rrrrrrrr', 'datanum', min_rang, max_range, datanum, Sentences['ChannelId'], the_text,
                  len(the_text))
            back_match = get_result_matching_rule_6(
                fast_ignore, fast_num, role, the_text, Sentences, taskid)
            if back_match == 1:
                is_match = 1
        elif min_rang != None and max_range == None and min_rang <= datanum:
            print('qqqqqqqqq', 'datanum', min_rang, max_range, datanum, Sentences['ChannelId'], the_text,
                  len(the_text))
            back_match = get_result_matching_rule_6(
                fast_ignore, fast_num, role, the_text, Sentences, taskid)
            if back_match == 1:
                is_match = 1
        elif max_range != None and min_rang == None and max_range >= datanum:
            print('aaaaaaaaaaaa', 'datanum', min_rang, max_range, datanum, Sentences['ChannelId'], the_text,
                  len(the_text))
            back_match = get_result_matching_rule_6(
                fast_ignore, fast_num, role, the_text, Sentences, taskid)
            if back_match == 1:
                is_match = 1
        return is_match
    except Exception as e:
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))
        return is_match


# 匹配ctype=6的规则(语速过快)
def matching_rule_6(voice_result, fast_num, fast_ignore, role, range, min_rang, max_range, taskid, sampleid):
    # role(1所有角色 2坐席 3客户)
    is_match = 2  # 1:命中2：未命中
    try:
        print(fast_num, fast_ignore, role, range,
              min_rang, max_range, taskid, voice_result)
        if voice_result:
            Sentences_list = voice_result['Result']['Sentences']
            # ChannelId_service_list = []  # 说话人0：客服
            # ChannelId_client_list = []  # 1：客户
            datanum = 0
            for i, Sentences in enumerate(Sentences_list):
                the_text = re.sub(
                    "[\s+\.\!\/_,$%^*(+\"\']+|[+——！，。？、~@#￥%……&*（）]+", "", str(Sentences['Text']))
                the_text = the_text.replace(" ", "")
                print(i, Sentences['ChannelId'], len(the_text), )
                if range == 1:
                    print('FFFFFFF')
                    back_match = get_result_matching_rule_6(fast_ignore, fast_num, role, the_text, Sentences,
                                                            taskid)
                    if back_match == 1:
                        is_match = 1
                else:
                    if role == 1:
                        datanum += 1
                        back_match = get_rang_matching_rule_6(min_rang, max_range, datanum, fast_ignore, fast_num, role,
                                                              the_text,
                                                              Sentences, taskid)
                        if back_match == 1:
                            is_match = 1
                    if role == 2 and Sentences['ChannelId'] == 1:
                        datanum += 1
                        back_match = get_rang_matching_rule_6(min_rang, max_range, datanum, fast_ignore, fast_num,
                                                              role,
                                                              the_text,
                                                              Sentences, taskid)
                        if back_match == 1:
                            is_match = 1
                    if role == 3 and Sentences['ChannelId'] == 0:
                        datanum += 1
                        back_match = get_rang_matching_rule_6(min_rang, max_range, datanum, fast_ignore, fast_num,
                                                              role,
                                                              the_text,
                                                              Sentences, taskid)
                        if back_match == 1:
                            is_match = 1
                    # print('datanum',datanum,min_rang,max_range,datanum)

        return is_match
    except Exception as e:
        weixin_push(str(taskid) + " " + str(sampleid),
                    str(e), '质检错误matching_rule_6')
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))
        return is_match


# 统计客服最大静音时长
def get_mute_time(voice_result, channel, taskid):
    time = 0
    try:
        if voice_result:
            Sentences_list = voice_result['Result']['Sentences']
            for Sentences in Sentences_list:
                if Sentences['ChannelId'] == channel:
                    if Sentences['SilenceDuration'] > time:
                        time = Sentences['SilenceDuration']
        return time
    except Exception as e:
        weixin_push(str(taskid), str(e), '质检错误get_mute_time')
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))
        return time


# 匹配ctype=7的规则(静音) 时长要大于
def matching_rule_7(role, range, min_rang, max_range, mute_time, voice_result, taskid, sampleid):
    # role(1所有角色 2坐席 3客户)
    is_match = 2  # 1:命中2：未命中
    print((role, range, min_rang, max_range, mute_time, voice_result, taskid))
    try:
        if voice_result:
            Sentences_list = voice_result['Result']['Sentences']
            time_surpass = 0
            ChannelId_service_list = []  # 说话人0：客服
            ChannelId_client_list = []  # 1：客户
            datanum = 0
            for i, Sentences in enumerate(Sentences_list):
                print(Sentences['SilenceDuration'],
                      Sentences['ChannelId'], mute_time, i, Sentences["Text"])
                if role == 1 and range == 1 and Sentences['SilenceDuration'] > mute_time:
                    is_match = 1
                elif role == 2 and Sentences['ChannelId'] == 1:  # 客服
                    datanum += 1
                    print('SSS', Sentences['ChannelId'],
                          Sentences['SilenceDuration'], datanum)
                    if range == 1 and Sentences['SilenceDuration'] > mute_time:
                        is_match = 1
                    elif range == 2 and Sentences['SilenceDuration'] > mute_time:
                        print(3333333333444444444, min_rang,
                              datanum, max_range, Sentences["Text"])
                        if min_rang != None and max_range != None and min_rang <= datanum <= max_range:
                            is_match = 1
                        elif min_rang == None and max_range != None and datanum <= max_range:
                            is_match = 1
                        elif min_rang != None and max_range == None and datanum >= min_rang:
                            is_match = 1
                elif role == 3 and Sentences['ChannelId'] == 0:  # 客服
                    datanum += 1
                    if range == 1 and Sentences['SilenceDuration'] > mute_time:
                        is_match = 1
                    elif range == 2 and Sentences['SilenceDuration'] > mute_time:
                        print(566666666666, min_rang, datanum,
                              max_range, Sentences["Text"])
                        if min_rang != None and max_range != None and min_rang < datanum < max_range:
                            is_match = 1
                        elif min_rang == None and max_range != None and datanum <= max_range:
                            is_match = 1
                        elif min_rang != None and max_range == None and datanum >= min_rang:
                            is_match = 1

        return is_match
    except Exception as e:
        print(" matching_rule_7 ", e)
        weixin_push(str(taskid) + " " + str(sampleid),
                    str(e), '质检错误matching_rule_7')
        qa_logger.error('task_id:%s error:%s %s', taskid, type(e), str(e))
        return is_match


class ThreadWithReturnValue(Thread):
    def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, daemon=None):
        Thread.__init__(self, group, target, name, args, kwargs, daemon=daemon)

        self._return = None

    def run(self):
        if self._target is not None:
            self._return = self._target(*self._args, **self._kwargs)

    def join(self):
        Thread.join(self)
        return self._return


def begin_quality_task(task_id, cmp_id):
    """
    开始检测任务，将检测任务中的全部录音。
    :param task_id: 任务编号
    :param cmp_id: 公司编号
    :return:
    """
    not_back_voice_data_list = get_task_quality_service_data(
        task_id=task_id, state=1)
    qa_logger.info('task_id:%s not_back_voice_data_list:%s',
                   task_id, not_back_voice_data_list)

    for not_back_voice_data in not_back_voice_data_list:
        if memcachcon.if_exist('{}begin_quality_test_task{}'.format(conn.basedbname, task_id)) == 'True':
            print('kkkkkkssss', not_back_voice_data)
            result_data = get_reault_voice_translate(not_back_voice_data['voice_taskid'],
                                                     not_back_voice_data['sampleid'], task_id, cmp_id)
            not_back_voice_data['voice_result'] = result_data['result']
            if result_data['code'] == '1':
                begin_quality(task_id, not_back_voice_data, cmp_id, 1, '')
        else:
            break
    # 查询是否还有数据没质检
    count_num = sel_count_quality_data(task_id)
    task_state = memcachcon.if_exist(
        '{}begin_quality_test_task{}'.format(conn.basedbname, task_id))
    qa_logger.info('task_id:%s count_num:%s task_state:%s',
                   task_id, count_num, task_state)
    if count_num != 0 and task_state == 'True':
        qa_logger.info('数据未翻译，重新提交翻译 task_id:%s count_num:%s task_state:%s',
                       task_id, count_num, task_state)
        time.sleep(5)
        quality_data_dict = get_task_quality_service_data(
            task_id=task_id, state=0)
        cycle_translate_voice(quality_data_dict, task_id)
        begin_quality_task(task_id, cmp_id)
        # s.enter(180, 0, aliyun_voice_translate,(taskid,cmpid))
    elif count_num == 0:
        # 更新质检任务状态为质检完成
        qa_logger.info('质检完成 task_id:%s task_state:%s', task_id, task_state)
        updata_quality_state(task_id)
        memcachcon.del_cach(
            '{}begin_quality_test_task{}'.format(conn.basedbname, task_id))


# New time_qualiting
def begin_single_quality_task(task_id, cmp_id, sample_id):
    """
    开始检测任务中的单条录音
    :param task_id: 任务编号
    :param cmp_id: 公司编号
    :param sample_id:单条录音编号
    :return:
    """

    try:
        qa_logger.info('开始单条质检 task_id:%s sample_id:%s', task_id, sample_id)
        # 得到检测的数据
        not_back_voice_data_list = get_task_single_quality_service_data(task_id=task_id, sample_id=sample_id,
                                                                        state=0)  # scid

        the_error_aliyun = 0
        if not not_back_voice_data_list:
            # 不存在数据 结束检测
            return
        not_back_voice_data_list = not_back_voice_data_list[0]
        # 录音识别
        do_voice(not_back_voice_data_list, task_id, sample_id)
        aliyun_taskid = memcachcon.if_exist('%staskid%s%s' % (
            conn.basedbname, task_id, sample_id))  # 是否存在任务ID
        memcachcon.set_cach('%sA_scid%s' % (
            conn.basedbname, sample_id), not_back_voice_data_list["scid"])
        # 不存在任务id
        if not aliyun_taskid:
            print('不存在任务ID，已结束')
            del_quality_data(sample_id, task_id)  # 删除之前的记录
            memcachcon.del_cach('%staskid%s%s' %
                                (conn.basedbname, task_id, sample_id))
            unusual_voice_soce(cmp_id, task_id, sample_id, 5, 1)
            memcachcon.del_cach('%sA_scid%s' % (conn.basedbname, sample_id))
            weixin_push(str(task_id), "sampleid" + str(sample_id),
                        '质检错误time_qualiting 没有aliyun_taskid')
            return None  # 提前结束

        # 当任务ID存在

        time.sleep(0.3)
        # 获取阿里云翻译结果
        aliyun_task_id = aliyun_taskid['taskid']
        result_data = get_reault_voice_translate(
            aliyun_task_id, sample_id, task_id, cmp_id)
        not_back_voice_data_list['voice_taskid'] = aliyun_task_id
        while result_data['code'] == '2':
            # 此循环主要是为了在连接超时的情况下进行重试，重试次数为3次
            # 存储检测任务开始时间
            begin_time = memcachcon.if_exist(
                '%sbegin_single_quality_task_begin%s' % (conn.basedbname, sample_id))
            if begin_time is None:
                break
            end_time = datetime.datetime.now().replace(microsecond=0)
            task_ttl = (
                end_time - datetime.datetime.strptime(begin_time, "%Y-%m-%d %H:%M:%S")).seconds
            if task_ttl > 60 * 20:  # 超过质检时间 20分钟
                retry_count = memcachcon.if_exist(
                    '%staskidcount%s' % (conn.basedbname, sample_id))
                if retry_count is None:
                    retry_count = 1
                    memcachcon.set_cach_not_time('%staskidcount%s' % (
                        conn.basedbname, sample_id), retry_count)
                else:
                    retry_count = int(retry_count) + 1
                    memcachcon.set_cach_not_time('%staskidcount%s' % (
                        conn.basedbname, sample_id), retry_count)
                if retry_count < 3:  # 没超总质检次数继续重新质检
                    begin_single_quality_task(task_id, cmp_id, sample_id)
                    break
                else:  # 超了质检次数
                    if task_ttl > 60 * 60:  # 最后一次质检时间超过多少就结束质检 1小时
                        the_error_aliyun = 1
                        weixin_push(str(task_id), "质检几次阿里云还超时",
                                    '智能质检time_qualiting')
                        break
                    else:  # 没超过时间继续质检最后一次
                        result_data = get_reault_voice_translate(
                            aliyun_task_id, sample_id, task_id, cmp_id)
            else:  # 没超过时间继续查询是否返回质检结果
                time.sleep(0.1)
                result_data = get_reault_voice_translate(
                    aliyun_task_id, sample_id, task_id, cmp_id)

        if result_data['code'] == '1':
            # 正常状态下
            not_back_voice_data_list['voice_result'] = result_data['result']
            begin_single_quality(
                task_id, not_back_voice_data_list, cmp_id, 1, '')
        if the_error_aliyun == 1:
            updata_quality_voice_taskid(
                aliyun_taskid, task_id, sample_id, '', 5)
            del_quality_data(sample_id, task_id)  # 删除之前的记录
            unusual_voice_soce(cmp_id, task_id, sample_id, 5, 1)

            # 清除标志位缓存
            memcachcon.del_cach('{}A_scid{}'.format(
                conn.basedbname, sample_id))
            memcachcon.del_cach('{}taskid{}'.format(
                conn.basedbname, sample_id))
            memcachcon.del_cach('{}taskidbegin{}'.format(
                conn.basedbname, sample_id))
            memcachcon.del_cach('{}taskidcount{}'.format(
                conn.basedbname, sample_id))
            # 查询是否好有没有质检完的，没有就更新
            cont_num = sel_count_quality_data(task_id)
            if int(cont_num) == 0:
                # 更新状态
                updata_quality_state(task_id)
    except Exception as e:
        weixin_push(str(task_id), str(e), '智能质检time_qualiting')
        qa_logger.error('task_id:%s sample_id:%s error:%s %s',
                        task_id, sample_id, type(e), str(e))

# 循环出来音频


def do_voice(quality_data, task_id, sample_id=''):
    try:
        # cache_key = '{}fileLink{}'.format(conn.basedbname, sample_id)
        file_link = '{}{}'.format(
            conn.quality_voice_dress, quality_data['voxfile'])
        # memcachcon.set_cach_not_time(cache_key, file_link)
        aliyun_voice_translate(file_link, task_id, sample_id)
    except Exception as e:
        weixin_push(str(task_id), str(e), '质检错误do_voice')
        qa_logger.error('task_id:%s sample_id:%s error:%s %s',
                        task_id, sample_id, type(e), str(e))


def cycle_translate_voice(quality_data_dict, task_id):
    """
    对任务内的音频进行循环翻译。
    :param quality_data_dict: 待检测的数据
    :param task_id: 任务编号
    :return: None
    """
    try:
        qa_logger.info('task_id:%s quality_data_dict:%s', task_id, quality_data_dict)
        for quality_data in quality_data_dict:
            sample_id = quality_data['sampleid']
            voxfile = quality_data['voxfile']

            # 确认任务已启动 再进行翻译
            task_begin = memcachcon.if_exist('{}begin_quality_test_task{}'.format(conn.basedbname, task_id))
            qa_logger.info('单条参数打印 task_id:%s quality_data:%s task_begin:%s', task_id, quality_data, task_begin)
            if task_begin == 'True':
                file_link = '{}{}'.format(conn.quality_voice_dress, voxfile)
                aliyun_voice_translate(file_link, task_id, sample_id)
            else:
                break
    except Exception as e:
        weixin_push(str(task_id), str(e), '质检错误cycle_translate_voice')
        qa_logger.error('task_id:%s error:%s %s', task_id, type(e), str(e))


# begin_quality_task(888,946,5)

# 启动程序检查是否还有质检任务每完成
def inspect_qulity():
    # t.taskid,t.cmpid,t.service_type
    quality_list = sel_quality_tasking()
    thread = locals()
    for quality in quality_list:
        memcachcon.del_cach('{}begin_quality_test_task{}'.format(conn.basedbname, quality['taskid']))
        thread['threadquality' + str(quality['taskid'])] = ThreadWithReturnValue(target=begin_quality_task, args=(
            quality['taskid'], quality['cmpid'], quality['service_type']))
    for quality in quality_list:
        thread['threadquality' + str(quality['taskid'])].start()
    # for quality in quality_list:
    #     thread['threadquality' + str(quality['taskid'])].join()


# inspect_qulity()

# 在线质检
# quality_type 类型1.开始通话2.结束通话3.主叫录音4.被叫录音
# 1:插入通话记录开始时间加录音
# 2插入通话记录结束时间
# 3主叫录音翻译和规则匹配
# 4被叫叫录音翻译和规则匹配
# in_out呼入呼出 1呼入2呼出
def online_inspection(quality_type, call_numb, called_numb, unix_begin_time, unix_end_time, voice_address, in_out,
                      sessionid, cause):
    try:
        sampleid = None
        taskid = None
        cmpid = None
        userid = None
        serviceid = None
        is_hangoff = 0
        qa_logger.info('quality_type:%s call_numb:%s called_numb:%s unix_begin_time:%s unix_end_time:%s voice_address:%s in_out:%s sessionid:%s cause:%s',
                       quality_type, call_numb, called_numb, unix_begin_time, unix_end_time, voice_address, in_out, sessionid, cause)
        if quality_type != 1:
            sampleid = memcachcon.if_exist(str(conn.basedbname) + 'qualiting_sampleid' + str(sessionid))
            taskid = memcachcon.if_exist(str(conn.basedbname) + 'qualiting_taskid' + str(sessionid))
            cmpid = memcachcon.if_exist(str(conn.basedbname) + 'qualiting_cmpid' + str(sessionid))
            userid = memcachcon.if_exist(str(conn.basedbname) + 'qualiting_userid' + str(sessionid))
            serviceid = memcachcon.if_exist(str(conn.basedbname) + 'qualiting_serviceid' + str(sessionid))
            qa_logger.info('taskid:%s sampleid:%s cmpid:%s userid:%s serviceid:%s',
                           taskid, sampleid, cmpid, userid, serviceid)

        # 在线查询对应的会话编码并保存做记录，质检存开始时候和录音文件
        if quality_type == 1:
            # 查找客服编码
            user_data = get_useid(call_numb, sessionid)
            qa_logger.info('taskid:%s sampleid:%s user_data:%s', taskid, sampleid, user_data)
            cmpid = ''
            if len(user_data) > 0:
                cmpid = user_data[0]["companyid"]
                userid = user_data[0]["UserID"]
                memcachcon.set_cach_not_time(str(conn.basedbname) + 'qualiting_userid' + str(sessionid),
                                             user_data[0]["UserID"])
            memcachcon.set_cach_not_time(str(conn.basedbname) + 'qualiting_begintime' + str(sessionid),
                                         unix_begin_time)
            # 查找任务编码
            task_data = get_tasid(called_numb, sessionid, cmpid)
            taskid = ''

            if len(task_data) > 0:
                taskid = task_data[0]['taskid']
                cmpid = task_data[0]['cmpid']
                memcachcon.set_cach_not_time(str(conn.basedbname) + 'qualiting_taskid' + str(sessionid), taskid)
                memcachcon.set_cach_not_time(str(conn.basedbname) + 'qualiting_cmpid' + str(sessionid), cmpid)
            if userid and cmpid and taskid:
                # 查询质检的开始时间和结束时间
                quality_the_time = sel_quality_time(cmpid, taskid)
                qa_logger.info('quality_the_time:%s', quality_the_time)
                qa_logger.info('task_id:%s quality_the_time:%s', taskid, quality_the_time)
                the_begintime = 1
                the_endtime = 3
                the_now_tome = 2
                if len(quality_the_time) > 0:
                    the_begintime = time.strptime(str(quality_the_time[0]['time_begin']), "%H:%M:%S")
                    the_endtime = time.strptime(str(quality_the_time[0]['time_end']), "%H:%M:%S")
                    the_now_tome = time.strptime(
                        time.strftime("%H:%M:%S"), "%H:%M:%S")
                if the_begintime < the_now_tome <= the_endtime:
                    isinside = 2 if in_out == 1 else 3
                    # 插入zt_service_cust表
                    serviceid = insert_service_cust(cmpid, isinside, unix_begin_time, voice_address, taskid, userid,
                                                    call_numb, called_numb)
                    memcachcon.set_cach_not_time(str(conn.basedbname) + 'qualiting_serviceid' + str(sessionid),
                                                 serviceid)
                    # 插入zt_gc_ai_sample表
                    sampleid = insert_gc_ai_sample(serviceid, taskid)
                    memcachcon.set_cach_not_time(str(conn.basedbname) + 'qualiting_sampleid' + str(sessionid),
                                                 sampleid)
                    # 存入规则命中情况
                    unusual_voice_soce(cmpid, taskid, sampleid, 5, 2)
            return is_hangoff
        elif quality_type == 3 or quality_type == 4:
            if sampleid and cmpid and userid and taskid:
                datajson = Voicerecognition(1, voice_address, time.time())
                data = json.loads(datajson)
                print(data, 'dddfffff')
                text = data['text']
                # 插入聊天记录
                text = '你们在哪里'
                typeid = 1 if quality_type == 3 else 2
                if text != "":
                    # 结巴分词并且存到数据库
                    jieba_data = p(
                        re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+——！，。？、~@#￥%……&*（）]+", "", str(text)))
                    print('dddd', jieba_data)
                    ChannelId = 1 if quality_type == 3 else 0
                    insert_wordlist(jieba_data, taskid,
                                    sampleid, '', ChannelId)
                    # 插入聊天记录
                    print('ddd', (typeid, text, voice_address, sampleid, taskid))
                    insert_record_data(
                        typeid, text, voice_address, sampleid, sessionid)
                    word_count = words_minute(unix_begin_time, unix_end_time, len(unix_end_time),
                                              sessionid)  # 每分钟字数
                    print('word_count', word_count)
                    # 记录上一句的说话结束时间
                    voice_endtime = memcachcon.if_exist(
                        str(conn.basedbname) + 'voice_endtime' + str(sessionid))
                    quiet_time = 0
                    if voice_endtime != None:
                        quiet_time = the_quiet_time(
                            sessionid, voice_endtime, unix_begin_time)  # 静音时长存
                    voice_result = memcachcon.if_exist(
                        str(conn.basedbname) + 'voice_result' + str(sessionid))
                    print('voice_resultdddd', voice_result)

                    questionid = mongorobot.getanwqualityquestion(cmpid, text, '', '', '', '', '', '',
                                                                  '', conn.basedbname)
                    print('questionid', questionid)
                    if questionid and questionid[0] == 'A':
                        # 插入质检匹配到的数据库
                        insert_question_id(questionid[1:], sampleid, sessionid)
                    text_json = {
                        'EndTime': int(unix_end_time),
                        'SilenceDuration': int(quiet_time),
                        'BeginTime': int(unix_begin_time),
                        'Text': text,
                        'ChannelId': ChannelId,
                        'SpeechRate': word_count,
                        'EmotionValue': 0,
                        'voice': voice_address
                    }
                    if voice_result != None:
                        voice_result['Result']['Sentences'].append(text_json)
                        print('voice_result', voice_result)
                        memcachcon.set_cach_not_time(str(conn.basedbname) + 'voice_result' + str(sessionid),
                                                     voice_result)
                    else:
                        voice_result = {'BizDuration': 0, 'Result': {
                            'Words': [], 'Sentences': [text_json]}}
                        print('voice_result', voice_result)
                        memcachcon.set_cach_not_time(str(conn.basedbname) + 'voice_result' + str(sessionid),
                                                     voice_result)
                    # 开始质检
                    print('voice_result', voice_result)
                    is_hangoff = begin_quality(taskid, {'voice_result': str(voice_result), 'sampleid': sampleid,
                                                        'cause': cause}, cmpid, 2, userid)
            if memcachcon.if_exist(str(conn.basedbname) + 'hangup' + str(sampleid)) != None:
                qa_logger.info(
                    'have_hangup task_id:%s sampleid:%s', taskid, sampleid)
                is_hangoff = 1
            return is_hangoff
        elif quality_type == 2:  # 结束
            if sampleid and cmpid and userid and taskid:
                voice_result = memcachcon.if_exist(
                    str(conn.basedbname) + 'voice_result' + str(sessionid))
                memca_begintime = memcachcon.if_exist(
                    str(conn.basedbname) + 'qualiting_begintime' + str(sessionid))
                # 计算录音总时长(毫秒)
                print(memca_begintime, voice_result)
                all_time = (parse(str(unix_end_time)) -
                            parse(str(memca_begintime))).seconds * 1000
                print('all_time', all_time, voice_result)
                if voice_result == None:
                    print('sssssssssssss')
                    voice_result = {'BizDuration': 0, 'Result': {
                        'Words': [], 'Sentences': []}}
                voice_result['BizDuration'] = all_time
                print('voice_resultdd', voice_result)
                # 存储通话时间并且保存质检记录
                begin_quality(taskid, {'voice_result': str(voice_result), 'sampleid': sampleid, 'cause': cause},
                              cmpid,
                              3, userid)
                # 更新zt_gc_ai_sample表翻译的结果
                voice_result = memcachcon.if_exist(
                    str(conn.basedbname) + 'voice_result' + str(sessionid))
                updata_quality_voice_taskid(
                    '', taskid, sampleid, voice_result, 4)
                # 存结束时间到数据库
                update_service_cust(serviceid, sessionid, unix_end_time)
                # 删除缓存---------------
                del_quality_memcached(sessionid, sampleid)
            return is_hangoff

    except Exception as e:
        weixin_push(str(sessionid), str(e), '在线质检错误online_inspection')
        qa_logger.error('task_id:%s error:%s %s', sessionid, type(e), str(e))
        return 0


# 在线质检挂断操作
def online_inspection_hangup(sampleid):
    memcachcon.set_cach_not_time(
        str(conn.basedbname) + 'is_hangoffsampleid' + str(sampleid), 1)
    memcachcon.set_cach_not_time(
        str(conn.basedbname) + 'hangup' + str(sampleid), 1)


# 删除在线质检缓存
def del_quality_memcached(sessionid, sampleid):
    if memcachcon.if_exist(str(conn.basedbname) + 'qualiting_sampleid' + str(sessionid)):
        memcachcon.del_cach(str(conn.basedbname) +
                            'qualiting_sampleid' + str(sessionid))
    if memcachcon.if_exist(str(conn.basedbname) + 'qualiting_taskid' + str(sessionid)):
        memcachcon.del_cach(str(conn.basedbname) +
                            'qualiting_taskid' + str(sessionid))
    if memcachcon.if_exist(str(conn.basedbname) + 'qualiting_cmpid' + str(sessionid)):
        memcachcon.del_cach(str(conn.basedbname) +
                            'qualiting_cmpid' + str(sessionid))
    if memcachcon.if_exist(str(conn.basedbname) + 'qualiting_userid' + str(sessionid)):
        memcachcon.del_cach(str(conn.basedbname) +
                            'qualiting_userid' + str(sessionid))
    if memcachcon.if_exist(str(conn.basedbname) + 'qualiting_serviceid' + str(sessionid)):
        memcachcon.del_cach(str(conn.basedbname) +
                            'qualiting_serviceid' + str(sessionid))
    if memcachcon.if_exist(str(conn.basedbname) + 'voice_endtime' + str(sessionid)):
        memcachcon.del_cach(str(conn.basedbname) +
                            'voice_endtime' + str(sessionid))
    if memcachcon.if_exist(str(conn.basedbname) + 'voice_result' + str(sessionid)):
        memcachcon.del_cach(str(conn.basedbname) +
                            'voice_result' + str(sessionid))
    if memcachcon.if_exist(str(conn.basedbname) + 'qualiting_begintime' + str(sessionid)):
        memcachcon.del_cach(str(conn.basedbname) +
                            'qualiting_begintime' + str(sessionid))
    if memcachcon.if_exist(str(conn.basedbname) + 'is_hangoffsampleid' + str(sampleid)):
        memcachcon.del_cach(str(conn.basedbname) +
                            'is_hangoffsampleid' + str(sampleid))
    if memcachcon.if_exist(str(conn.basedbname) + 'hangup' + str(sampleid)):
        memcachcon.del_cach(str(conn.basedbname) + 'hangup' + str(sampleid))
    # 计算每分钟字数
    # {
    #     'EndTime': 25200,
    #     'SilenceDuration': 0,  # 静音时长
    #     'BeginTime': 23570,
    #     'Text': '你能贷多少钱？',
    #     'ChannelId': 1, 0是客户1是客服
    #     'SpeechRate': 220,  # 每分钟字数
    #     'EmotionValue': 7.1 情绪
    # },
    #


# 计算每分钟字数
def words_minute(begintime, endtime, word, sessionid):
    try:
        print(begintime, endtime, word, sessionid)
        alltime = round((int(endtime) - int(begintime)) / 1000, 2)
        minute_count = int((60 * word) / alltime)
        return minute_count
    except Exception as e:
        weixin_push(str(sessionid), str(e), '在线质检错误words_minute')
        qa_logger.error('sessionid:%s error:%s %s', sessionid, type(e), str(e))
        return 0


# 本句与上一句之间的静音时长
def the_quiet_time(sessionid, endtime, begintime):
    try:
        alltime = int((begintime - endtime) / 1000)
        return alltime
    except Exception as e:
        weixin_push(str(sessionid), str(e), '在线质检错误the_quiet_time')
        qa_logger.error('sessionid:%s error:%s %s', sessionid, type(e), str(e))
        return 0
